﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace IGolovkine.AoA.BinarySerialization
{
    [Serializable]
    public sealed class TypeMap : IBinarySerializable
    {
        private readonly Type[] _types;

        public TypeMap(IBinarySerializable[] array)
        {
            _types = array.Select(a => a.GetType()).ToArray();
        }

        private TypeMap(IBinaryReader reader)
        {
            int count = reader.ReadInt32();
            if (count == 0)
                return;

            _types = new Type[count];

            Type current = null;
            int next = reader.ReadInt32();
            for (int i = 0; i < count; i++)
            {
                if (i == next)
                {
                    current = Type.GetType(reader.ReadString());
                    if (i != count - 1)
                    {
                        next = reader.ReadInt32();
                    }
                }
                _types[i] = current;
            }
        }

        public void Serialize(IBinaryWriter writer)
        {
            Type lastType = null;
            writer.WriteInt32(_types.Length);
            for (int i = 0; i < _types.Length; i++)
            {
                Type current = _types[i];
                if (current != lastType || i == _types.Length - 1)
                {
                    writer.WriteInt32(i);
                    writer.WriteString(current.FullName);
                    lastType = current;
                }
            }
        }

        public IEnumerable<Type> GetMappedTypes()
        {
            return _types;
        }

        public Type GetMappedTypeAt(int index)
        {
            return _types[index];
        }

        public int Count
        {
            get { return _types.Length; }
        }
    }
}
